package api

import (
	"fmt"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gfile"
	"github.com/google/uuid"
	"github.com/zhang201702/zhang"
	"github.com/zhang201702/zhang/z"
	"github.com/zhang201702/zhang/zlog"
	"io"
	"reflect"
)

type Api interface {
	Register(s *zhang.ServerGF)
}

var apis = make(map[string]Api)
var ops = map[string]string{"list": "List", "fetch": "Fetch", "save": "Save", "delete": "Delete"}

func Register(s *zhang.ServerGF) {
	s.BindHandler("/upload", upload)
	s.BindHandler("/uuid", func(r *ghttp.Request) {
		r.Response.WriteJson(g.Map{
			"status": true,
			"data":   uuid.New().String(),
		})
	})
	s.BindHandler("/{_name}/{_op}", func(r *ghttp.Request) {
		name := r.GetString("_name")
		op := r.GetString("_op")
		a, ok := apis[name]
		if !ok {
			a = NewApi(name, name)
			apis[name] = a
			//newApi.Register(s)
		}
		inputs := []reflect.Value{reflect.ValueOf(r)}

		reflect.ValueOf(a).MethodByName(ops[op]).Call(inputs)
	})
	for name := range registerMap {
		api := registerMap[name](name)
		api.Register(s)
	}
}
func uploadFile(r *ghttp.Request, path string) (string, string) {
	f, _, e := r.FormFile("data")
	if e != nil {
		r.Response.Write(z.NewResult(nil, e))
	}
	defer f.Close()
	name := r.GetString("name")
	savePath := path + name
	// savePath := path + uuid.New().String()+"."+name
	fmt.Println(savePath)
	file, err := gfile.Create("html" + savePath)
	if err != nil {
		zlog.Error(err, "上传文件，生成文件异常")
		r.Response.Write(z.NewResult(nil, err))
		return "", ""
	}
	defer file.Close()
	if _, err := io.Copy(file, f); err != nil {
		r.Response.Write(z.NewResult(nil, err))
		return "", ""
	}
	return name, savePath
}

func upload(r *ghttp.Request) {
	_, path := uploadFile(r, "/../result/")
	if path != "" {
		r.Response.WriteJson(z.Map{"data": path, "status": true})
	}
}

type GetApiFunc func(name string) Api

var registerMap = map[string]GetApiFunc{}

func registerApi(name string, getApiFunc GetApiFunc) {
	registerMap[name] = getApiFunc
}
func NewApi(name, path string) (api Api) {
	if getApiFunc, ok := registerMap[name]; ok {
		api = getApiFunc(name)
	} else {
		api = NewBaseApi(name, path)
	}
	return api
}
